home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 379_01 / zoo210s.zoo / zooext.c < prev    next >
C/C++ Source or Header  |  1991-07-12  |  23KB  |  659 lines

  1. #ifndef LINT
  2. /* derived from: zooext.c 2.21 88/08/24 02:39:04 */
  3. /*$Source: /usr/home/dhesi/zoo/RCS/zooext.c,v $*/
  4. /*$Id: zooext.c,v 1.9 91/07/09 01:54:13 dhesi Exp $*/
  5. static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zooext.c,v $\n\
  6. $Id: zooext.c,v 1.9 91/07/09 01:54:13 dhesi Exp $";
  7. #endif /* LINT */
  8.  
  9. /*
  10. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  11. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  12. (C) Copyright 1991 Rahul Dhesi -- All rights reserved
  13. */
  14. /* Extract file from archive.  Extracts files specified in parameter-list
  15.    from archive zoo_path.  If none specified, extracts all files from
  16.    archive. */
  17.  
  18. #include "options.h"
  19. #include "zoo.h"
  20. #include "parse.h"      /* defines struct for parse() */
  21.  
  22. #include "portable.h"   /* portable I/O definitions */
  23. #include "machine.h"    /* machine-specific declarations */
  24.  
  25. #include "zooio.h"
  26. #include "various.h"
  27.  
  28. #ifndef NOSIGNAL
  29. #include <signal.h>
  30. #endif
  31.  
  32. #include "zoofns.h"
  33.  
  34. #ifdef MODE_BIN        /* will need fileno() from stdio.h */
  35. # include <stdio.h>
  36. #endif
  37.  
  38. void makepath PARMS((char *));
  39. int needed PARMS((char *, struct direntry *, struct zoo_header *));
  40. void putstr PARMS((char *));
  41.  
  42. #ifdef FATTR
  43. int setfattr PARMS ((char *, unsigned long));
  44. #endif /* FATTR */
  45.  
  46. extern int quiet;
  47.  
  48. #include "errors.i"
  49.  
  50. /* Following two are used by ctrl_c() also, hence declared here */
  51. char extfname[LFNAMESIZE];             /* filename of extracted file */
  52. char prtfname[LFNAMESIZE];             /* name of extracted file on screen */
  53. static ZOOFILE this_file;              /* file to extract */
  54.  
  55. static int tofile;                     /* true if not pipe or null device */
  56. extern unsigned int crccode;
  57. extern char *out_buf_adr;              /* address of output buffer */
  58.  
  59. void zooext(zoo_path, option)
  60. char *zoo_path, *option;
  61. {
  62. char *whichname;                          /* which name to extract */
  63. char matchname[PATHSIZE];                 /* for pattern matching only */
  64. #ifndef NOSIGNAL
  65. T_SIGNAL (*oldsignal)();        /* to save previous SIGINT handler */
  66. #endif
  67. ZOOFILE zoo_file;                         /* open archive */
  68. long next_ptr;                            /* pointer to within archive */
  69. struct zoo_header zoo_header;             /* header for archive */
  70. int status;                               /* error status */
  71. int exit_status = 0;                                /* exit status */
  72. int error_message;                                /* Whether to give error message */
  73. unsigned long disk_space;                 /* disk space left */
  74. int matched = 0;                          /* Any files matched? */
  75. int overwrite = 0;                        /* force overwrite of files? */
  76. int supersede = 0;                                /* supersede newer files? */
  77. int needdel = 0;                          /* extract deleted files too */
  78. int usepath = 2;                          /* use path for extraction */
  79. int todot = 0;                            /* extract relative to . */
  80. int badcrc_count = 0;                     /* how many files with bad CRC */
  81. int bad_header = 0;                       /* to avoid spurious messages later */
  82. long fiz_ofs = 0;                         /* offset where to start */
  83. long dat_ofs = 0;                                    /* .. and offset of file data */
  84. int pipe = 0;                             /* are we piping output? */
  85. int null_device = 0;                      /* are we sending to null device? */
  86. #ifndef PORTABLE
  87. int fast_ext = 0;                         /* fast extract as *.?Z? */
  88. int alloc_size;                           /* disk allocation unit size */
  89. #endif
  90. struct direntry direntry;                 /* directory entry */
  91. int first_dir = 1;                                /* first dir entry seen? */
  92.  
  93. static char extract_ver[] = "Zoo %d.%d is needed to extract %s.\n";
  94. static char no_space[] = "Insufficient disk space to extract %s.\n";
  95.  
  96. while (*option) {
  97.    switch (*option) {
  98. #ifndef PORTABLE
  99.       case 'z': fast_ext++; break;
  100. #endif
  101.       case 'x':
  102.       case 'e': break;
  103.       case 'N': null_device++; break;
  104.       case 'O': overwrite += 2; break;
  105.       case 'o': overwrite++; break;
  106.       case 'p': pipe++; break;
  107.         case 'S': supersede++; break;
  108.       case 'd': needdel++; break;
  109.       case 'q': quiet++; break;
  110.         case ':': usepath = 0; break;
  111.       case '/': usepath++; break;
  112.       case '.': todot++; break;
  113.       case '@':     /* if @m,n specified, fiz_ofs = m, dat_ofs = n */
  114.             {
  115.                 char *comma_pos;
  116.                 ++option;
  117.                 comma_pos = strchr(option, ',');
  118.                 if (comma_pos != NULL) {
  119.                     dat_ofs = calc_ofs (comma_pos + 1);
  120.                     *comma_pos = '\0';
  121.                 }
  122.                 fiz_ofs = calc_ofs(option); 
  123.                 goto no_more;
  124.             }
  125.       default:
  126.          prterror ('f', inv_option, *option);
  127.          /* break; */
  128.    }
  129.    option++;
  130. }
  131.  
  132. no_more: /* come from exit in while loop above */
  133.  
  134.  
  135. if (overwrite == 1)                 /* must be at least 2 to begin with */
  136.    overwrite--;
  137.  
  138. if (null_device && pipe) {
  139.    prterror ('f', inv_option, 'p');
  140.    pipe = 0;
  141. }
  142.  
  143. if (overwrite && pipe)
  144.    prterror ('w', option_ignored, 'O');
  145.  
  146. #ifndef PORTABLE
  147. if (null_device && fast_ext) {
  148.    prterror ('w', inv_option, 'N');
  149.    null_device = 0;
  150. }
  151. #endif
  152.  
  153. tofile = !pipe && !null_device;     /* sending to actual file */
  154.  
  155. zoo_file = zooopen(zoo_path, Z_READ);
  156.  
  157. if (zoo_file == NOFILE)
  158.    prterror ('f', could_not_open, zoo_path);
  159.  
  160. if (fiz_ofs != 0L) {                /* if offset specified, start there */
  161.     prterror ('m', start_ofs, fiz_ofs, dat_ofs);
  162.    zooseek (zoo_file, fiz_ofs, 0);
  163. } else {
  164.    /* read header */
  165.    frd_zooh (&zoo_header, zoo_file);
  166.    if ((zoo_header.zoo_start + zoo_header.zoo_minus) != 0L) {
  167.       prterror ('w', failed_consistency);
  168.       bad_header++;
  169.         exit_status = 1;
  170.    }
  171.    zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
  172. }
  173.  
  174. #ifndef PORTABLE
  175. disk_space = space (0, &alloc_size);         /* remember disk space left */
  176. #else
  177. disk_space = MAXLONG;              /* infinite disk space */
  178. #endif
  179.  
  180. /* if piping output we open the output device just once */
  181. if (null_device) {
  182.    this_file = NULLFILE;
  183. } else if (pipe)
  184.    this_file = STDOUT;    /* standard output */
  185.  
  186. while (1) {
  187.    frd_dir (&direntry, zoo_file);
  188.    if (direntry.zoo_tag != ZOO_TAG) {
  189.       long currpos, zoolength;
  190.         prterror ('F', invalid_header);
  191.  
  192.         /* Note:  if header was bad, there's no point trying to find
  193.             how many more bytes aren't processed -- our seek position is
  194.             likely very wrong */
  195.  
  196.         if (!bad_header)
  197.             if ((currpos = zootell (zoo_file)) != -1L)
  198.                 if (zooseek (zoo_file, 0L, 2) != -1)
  199.                     if ((zoolength = zootell (zoo_file)) != -1L)
  200.                         printf (cant_process, zoolength - currpos);              
  201.         zooexit (1);
  202.    }
  203.    if (direntry.next == 0L) {                /* END OF CHAIN */
  204.       break;                                 /* EXIT on end of chain */
  205.    }
  206.     /* when first direntry read, change dat_ofs from abs. pos. to rel. offset */
  207.     if (first_dir && dat_ofs != 0) {
  208.         dat_ofs -= direntry.offset;
  209.         first_dir = 0;
  210.     }
  211.    next_ptr = direntry.next + dat_ofs;       /* ptr to next dir entry */
  212.  
  213.    whichname = choosefname(&direntry);       /* which filename */
  214.     whichname = str_dup(whichname);                /* bug fix */
  215.    fixfname(whichname);                      /* fix syntax */
  216.     strcpy (matchname, fullpath (&direntry));    /* get full pathname */
  217.     if (zoo_header.vdata & VFL_ON)
  218.         add_version (matchname, &direntry);        /* add version suffix */
  219.  
  220. /* if extraction to subtree rooted at curr dir, modify pathname */
  221. #if 0
  222. #ifdef DIR_LBRACK
  223.    if (todot && direntry.dirname[0] == *DIR_LBRACK &&
  224.                 direntry.dirname[1] != *CUR_DIR)      {
  225.       char tmpstr[PATHSIZE];
  226.       strcpy (tmpstr, DIR_LBRACK);
  227.       strcat (tmpstr, CUR_DIR);
  228.       strcat (tmpstr, &direntry.dirname[1]);
  229.       strcpy (direntry.dirname, tmpstr);
  230.    }
  231. #endif
  232. #endif
  233.  
  234.    /* hard-coded '/' should be eventually removed */
  235.    if (todot && *direntry.dirname == '/') { 
  236.       char tmpstr[PATHSIZE];
  237.       strcpy(tmpstr, direntry.dirname);
  238.       strcpy(direntry.dirname,CUR_DIR);
  239.       strcat(direntry.dirname, tmpstr);
  240.    }
  241.  
  242.    /* matchname now holds the fu